<template>
  <div class="user-login">
    <!-- 导航栏 -->
    <van-nav-bar title="登录"></van-nav-bar>
    <!-- 表单部分
      vant里边没有form相关组件，只有普通表单域组件
      van-cell-group是对普通表单域组件做封装
    -->
    <van-cell-group>
      <!--van-field 输入框表单域组件
        label="手机号" 表单域前边的名字设置
        required：不进行校验，设置表单域前边有"红星"
        clearable：表单域内容可以通过“叉号”清除
      -->

      <!-- ValidationProvider配置属性，以完成校验
      rules：配置校验规则
      name="手机号" 设置项目名称，校验失败的时候给出的提示
      v-slot：作用域插槽，用于接收校验的错误信息
      v-slot="scope" 表单校验失败接收错误信息 ：{{scope.errors[0]}}

       v-slot="{ errors }" 对象解构赋值
       表单校验失败接收错误信息：{{errors[0]}}

       v-slot应用场合：template标签、组件标签
       slot-scope应用场合：template标签、组件标签、普通的html标签

       ValidationProvider 接收插槽数据必须使用v-slot，不能用slot-scope
       该组件内部规则决定的

       v-slot与slot-scope作用相似，都是用于接收插槽数据
       error-message:给输入框设置表单校验的错误信息，是vant组件库提供的方法
      -->
      <!-- 注意：required|phone  |竖线 左右不要设置空格-->
      <ValidationObserver ref="loginFormRef">
        <ValidationProvider name="手机号" rules="required|phone" v-slot="{ errors }">
          <van-field
            v-model="loginForm.mobile"
            type="tel"
            placeholder="请输入手机号码"
            label="手机号"
            required
            clearable
            :error-message="errors[0]"
          ></van-field>
        </ValidationProvider>
        <ValidationProvider name="验证码" rules="required" v-slot="{ errors }">
          <van-field
            v-model="loginForm.code"
            type="password"
            placeholder="请输入验证码"
            label="验证码"
            required
            clearable
            :error-message="errors[0]"
          >
            <!-- 命名插槽应用，提示相关按钮，是要给van-field组件内部的slot去填充的
        size="small" 设置按钮大小的
        type="primary" 设置按钮背景颜色
            -->
            <van-button slot="button" size="small" type="primary">发送验证码</van-button>
          </van-field>
        </ValidationProvider>
      </ValidationObserver>
    </van-cell-group>
    <div class="login-btn">
      <!--van-button
        type:按钮背景颜色
        size:按钮大小的
        round：圆边效果
        block：块级样式设置，占据一行
      -->
      <van-button
        type="info"
        size="small"
        round
        block
        @click="login()"
        :loading="isLogin"
        loading-text="登录中..."
      >登录</van-button>
    </div>
  </div>
</template>

<script>
// 1.导入验证表单项相关模块(ValidationProvider)
// 2.导入验证全部表单项模块(ValidationObserver)
import { ValidationProvider, ValidationObserver } from 'vee-validate'

// 导入账号校验的api函数
import { apiUserLogin } from '@/api/user.js'

export default {
  name: 'user-chat',
  data () {
    return {
      // 登录按钮加载中的效果(true:加载中  false:停止加载)
      isLogin: false,

      loginForm: {
        // 登录表单数据对象，字段名称来自后台接口
        mobile: '13911111111', // 手机号码
        code: '246810' // 验证码
      }
    }
  },
  components: {
    // 注册验证组件
    ValidationProvider,
    ValidationObserver
  },
  methods: {
    async login () {
      // 对全部表单项目做校验，没有问题再向下执行
      // ValidationObserver
      // validate()返回promise对象
      // valid=true  校验成功    valid=false  校验失败
      const valid = await this.$refs.loginFormRef.validate()
      // console.log(valid)
      if (!valid) {
        // 若校验失败，停止后续代码的执行
        return false
      }

      // 当全部的表单校验完毕后，将“登录”按钮设置为“登录中”的状态
      this.isLogin = true

      // apiUserLogin函数执行的时候，有可能成功，也可能失败，所以需要使用try/catch进行判断，捕捉错误信息
      try {
        // 校验账号有效性
        // 所有api函数返回的结果就是axios的返回结果，就是Promise对象
        const result = await apiUserLogin(this.loginForm)
        // api函数执行成功，代表账号正确
        // 如果报400的错误信息，代表账号错误，并且是致命错误，会阻止后续程序代码运行
        // 因此，判断账号是否正确，不用通过result返回值，需要try/catch介入
        // console.log(result) // {token:xxx, refresh_token:xxx}

        // 通过Vuex(调用store/index.js文件，已在main.js中进行了全局引入)对当前用户登录后返回的状态秘钥信息进行保存(即：token & refresh)
        this.$store.commit('updateUser', result)
      } catch (err) {
        // 恢复按钮(取消加载效果)
        this.isLogin = false

        // 账号错误，this.$toast.fail()是vant组件库提供的“错误提示”语法信息
        // 与element-ui 提供的this.$message.error()是一样的效果
        // return 表示停止后续代码执行，并提示错误信息
        return this.$toast.fail('用户名或密码错误' + err)
      }

      // 登录成功的提示信息
      this.$toast.success('登录成功')
      // 页面跳转到首页
      this.$router.push('/home')

      // 恢复按钮(取消加载效果)
      this.isLogin = false
    }
  }
}
</script>

<style scoped lang='less'>
.login-btn {
  margin: 40px;
}
</style>
